﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Web.Caching;
using ChannelVN.Cached.CacheClients;
using ChannelVN.Cached.Common;
using ChannelVN.Cached.Config;
using ChannelVN.Cached.Entity;
using CacheDependency = ChannelVN.Cached.CacheClients.CacheDependency;

namespace ChannelVN.Cached
{
    public class CacheController
    {
        public static bool IsCachedUpdating
        {
            get
            {
                if (QueryStrings.CachedSecurityKey.Equals(Lib.MD5Encrypt(AppConfigs.SecretCacheKey), StringComparison.CurrentCultureIgnoreCase))
                {
                    return QueryStrings.IsCachedUpdating;
                }
                else
                {
                    return false;
                }
            }
        }
        public static bool IsCachedDeleting
        {
            get
            {
                if (QueryStrings.CachedSecurityKey.Equals(Lib.MD5Encrypt(AppConfigs.SecretCacheKey), StringComparison.CurrentCultureIgnoreCase))
                {
                    return QueryStrings.IsCachedDeleting;
                }
                else
                {
                    return false;
                }
            }
        }

        public static CacheSettings CurrentCacheSettings
        {
            get
            {
                return CacheSettings.GetCurrentSettings();
            }
        }

        private static CacheDependency _cacheDependencyInstance;
        public static CacheDependency GetCacheDependencyInstance()
        {
            if (null == _cacheDependencyInstance)
            {
                _cacheDependencyInstance = new CacheDependency();
            }
            return _cacheDependencyInstance;
        }

        private static Dictionary<string, Memcached> _memcachedInstances;
        public static Memcached GetMemcachedInstance(string cacheClientName)
        {
            if (null == _memcachedInstances)
            {
                _memcachedInstances = new Dictionary<string, Memcached>();
            }
            Memcached instance = null;
            if (_memcachedInstances.ContainsKey(cacheClientName))
            {
                instance = _memcachedInstances[cacheClientName];
            }
            else
            {
                var count = CurrentCacheSettings.CacheClients.Length;
                for (var i = 0; i < count; i++)
                {
                    var cacheClient = CurrentCacheSettings.CacheClients[i];
                    if (cacheClient.Name != cacheClientName) continue;
                    instance = new Memcached(cacheClientName, cacheClient.ConfigSectionName);
                    instance.EnableCache = CacheSettings.GetCurrentSettings().EnableCache;

                    if (!_memcachedInstances.ContainsKey(cacheClientName))
                    {
                        _memcachedInstances.Add(cacheClientName, instance);
                    }
                    break;
                }
            }

            return instance;
        }
        public static Memcached GetMemcachedInstanceForDataCached()
        {
            if (null == _memcachedInstances)
            {
                _memcachedInstances = new Dictionary<string, Memcached>();
            }
            Memcached instance = null;
            var cacheClientName = CacheSettings.GetCurrentSettings().CacheClientForDataCached;
            if (_memcachedInstances.ContainsKey(cacheClientName))
            {
                instance = _memcachedInstances[cacheClientName];
            }
            else
            {
                var count = CurrentCacheSettings.CacheClients.Length;
                for (var i = 0; i < count; i++)
                {
                    var cacheClient = CurrentCacheSettings.CacheClients[i];
                    if (cacheClient.Name != cacheClientName) continue;
                    instance = new Memcached(cacheClientName, cacheClient.ConfigSectionName);
                    instance.EnableCache = CacheSettings.GetCurrentSettings().EnableCache &&
                                           CacheSettings.GetCurrentSettings().EnableDataCached;

                    if (!_memcachedInstances.ContainsKey(cacheClientName))
                    {
                        _memcachedInstances.Add(cacheClientName, instance);
                    }
                    break;
                }
            }

            return instance;
        }

        public static Memcached GetMemcachedInstanceForTag()
        {
            if (null == _memcachedInstances)
            {
                _memcachedInstances = new Dictionary<string, Memcached>();
            }
            Memcached instance = null;
            const string cacheClientName = "Tag";
            if (_memcachedInstances.ContainsKey(cacheClientName))
            {
                instance = _memcachedInstances[cacheClientName];
            }
            else
            {
                var count = CurrentCacheSettings.CacheClients.Length;
                for (var i = 0; i < count; i++)
                {
                    var cacheClient = CurrentCacheSettings.CacheClients[i];
                    if (cacheClient.Name != cacheClientName) continue;
                    instance = new Memcached(cacheClientName, cacheClient.ConfigSectionName);
                    instance.EnableCache = CacheSettings.GetCurrentSettings().EnableCache;

                    if (!_memcachedInstances.ContainsKey(cacheClientName))
                    {
                        _memcachedInstances.Add(cacheClientName, instance);
                    }
                    break;
                }
            }

            return instance;
        }

        public static void RemoveAllMemcachedGroup(string groupName)
        {
            var currentSimpleCachedKeyGroups = SimpleMemcachedKeyGroup.Current;
            if (currentSimpleCachedKeyGroups.ContaintsGroup(groupName))
            {
                var cacheKeys = currentSimpleCachedKeyGroups[groupName];
                foreach (var cacheKey in cacheKeys)
                {
                    var cacheClientNam = cacheKey.Substring(0, cacheKey.IndexOf("$"));
                    var key = cacheKey.Substring(cacheKey.IndexOf("$") + 1);
                    GetMemcachedInstance(cacheClientNam).Remove(groupName, cacheKey);
                }
            }
            currentSimpleCachedKeyGroups.RemoveGroup(groupName);
        }

        public static string GetCacheKeyName(string format, string cacheClientName)
        {
            var zone = QueryStrings.CachedZone.ToString();
            var news = QueryStrings.CachedNewsId.ToString();
            var tag = QueryStrings.CachedTagId.ToString();
            var page = QueryStrings.CachedPageIndex.ToString();
            var date = QueryStrings.CachedViewByDate;

            var cacheKey = format;
            cacheKey = cacheKey.Replace("{zone}", zone);
            cacheKey = cacheKey.Replace("{news}", news);
            cacheKey = cacheKey.Replace("{tag}", tag);
            cacheKey = cacheKey.Replace("{pageindex}", page);
            cacheKey = cacheKey.Replace("{date}", date);
            return cacheClientName + "$" + cacheKey;
        }

        public enum CacheGroupType
        {
            NoGroupCacheKey = 1,
            GroupCacheKey = 2
        }
        public const string CacheGroupForDataCached = "";
        public static string GetCacheGroup(CacheSettingConstants.GroupCachedKey groupCacheKey)
        {
            if (groupCacheKey != CacheSettingConstants.GroupCachedKey.NoGroup)
            {
                var zone = QueryStrings.CachedZone;
                var tag = QueryStrings.CachedTagId;
                var news = QueryStrings.CachedNewsId;

                switch (groupCacheKey)
                {
                    case CacheSettingConstants.GroupCachedKey.GroupByZone:
                        return "zone" + zone;
                    case CacheSettingConstants.GroupCachedKey.GroupByNews:
                        return "news" + news;
                    case CacheSettingConstants.GroupCachedKey.GroupByTag:
                        return "tag" + tag;
                    default:
                        return "";
                }
            }
            return "";
        }

    }
}
